pub trait StringExentd {
    /// 截取字符
    fn sub_char(&self, start_index: usize, len: usize) -> String;

    /// 截取字符为两段
    fn split_char2(&self, lable: impl AsRef<str>) -> (String, String);

    /// 以字符分隔为数组
    fn split_char(&self, lable: impl AsRef<str>) -> Vec<String>;
}

impl<T: AsRef<str>> StringExentd for T {
    /// 截取字符
    fn sub_char(&self, start_index: usize, len: usize) -> String {
        let value = self.as_ref();
        let v_len = value.chars().count();

        // 截取数据时, 验证长度够不够截取
        if v_len < start_index + len {
            return String::new();
        }

        let t = value.chars().into_iter().map(|x| x.to_string()).collect::<Vec<_>>();
        if len > t.len() {
            return "".to_owned();
        }
        let r: String = t[start_index..start_index + len].concat();
        return r;
    }
    /// 截取字符
    fn split_char2(&self, lable: impl AsRef<str>) -> (String, String) {
        let value = self.as_ref();
        let lable = lable.as_ref();
        let lable_len = lable.len();
        let value_len = value.len();

        let index = match value.find(&lable) {
            None => return (value.to_string(), String::new()),
            Some(v) => v,
        };

        let index_start = index;
        let lable_end = index + lable_len;

        let r: String = value[0..index_start].to_string();
        let r2: String = value[lable_end..value_len].to_string();
        (r, r2)
    }

    fn split_char(&self, lable: impl AsRef<str>) -> Vec<String> {
        let value = self.as_ref();
        let lable = lable.as_ref();
        let mut arr = vec![];
        let (s1, s2) = value.split_char2(lable);
        arr.push(s1);
        if s2.as_str() != "" {
            let mut arr2 = s2.split_char(lable);
            arr.append(&mut arr2);
        }
        arr
    }
}

#[test]
fn test_old_sub_char() {
    // 测试字符串的字节表示
    let s = String::from("测试获得bytes");
    let expected_bytes = "测试获得bytes".as_bytes();
    assert_eq!(s.as_bytes(), expected_bytes);

    // 测试截取中英混合字符串
    let a = "郭达b欢迎你";
    let v = a.sub_char(2, 1);
    assert_eq!(v, "b");

    // 测试截取中文字符
    let a = "郭达好欢迎你";
    let v = a.sub_char(2, 1);
    assert_eq!(v, "好");

    // 测试分割字符串 - 找不到分隔符的情况
    let a = "郭达欢迎你,查找一个找不到的中文字符";
    let v = a.split_char2("好");
    assert_eq!(v, (a.to_string(), String::new()));

    // 测试分割字符串 - 找不到英文字符的情况
    let a = "郭达欢迎你,查找一个找不到的英文字符呀";
    let v = a.split_char2("e");
    assert_eq!(v, (a.to_string(), String::new()));

    // 测试分割字符串 - 找到英文字符串的情况
    let a = "郭达欢迎你,ab查找一个英文字符串";
    let v = a.split_char2(",ab");
    assert_eq!(v, ("郭达欢迎你".to_string(), "查找一个英文字符串".to_string()));

    // 测试分割字符串 - 找到中文字符串的情况
    let a = "郭达欢迎你abc,你好查找一个中文字符串";
    let v = a.split_char2("你好");
    assert_eq!(v, ("郭达欢迎你abc,".to_string(), "查找一个中文字符串".to_string()));

    // 测试分割字符串 - 找到中英混合字符串的情况
    let a = "郭达abc欢迎你,查找一个中英混和字符串";
    let v = a.split_char2("abc欢迎你,");
    assert_eq!(v, ("郭达".to_string(), "查找一个中英混和字符串".to_string()));
}

#[test]
fn test_sub_char() {
    // 测试英文字符串截取
    let a = "abcdef";
    let v = a.sub_char(0, 2);
    assert_eq!(v, "ab");

    // 测试中英混合字符串截取
    let a = "郭达abc欢迎你";
    let v = a.sub_char(0, 2);
    assert_eq!(v, "郭达");

    // 测试 String 类型的截取
    let v = String::from("郭达abc欢迎你").sub_char(0, 3);
    assert_eq!(v, "郭达a");
}

#[test]
fn test_split_char2() {
    // 测试英文字符串分割
    let a = "abcd ef";
    let v = a.split_char2("c");
    assert_eq!(v, ("ab".to_string(), "d ef".to_string()));

    // 测试中文字符串用空格分割
    let a = "郭达 欢迎你";
    let v = a.split_char2(" ");
    assert_eq!(v, ("郭达".to_string(), "欢迎你".to_string()));

    // 测试中文字符串用中文分割
    let a = "郭达欢迎你";
    let v = a.split_char2("欢迎");
    assert_eq!(v, ("郭达".to_string(), "你".to_string()));

    // 测试找不到分隔符的情况
    let a = "郭达欢迎你";
    let v = a.split_char2("欢迎fd");
    assert_eq!(v, (a.to_string(), String::new()));

    // 测试中英混合分隔符
    let a = "郭达欢迎q你";
    let v = a.split_char2("欢迎q");
    assert_eq!(v, ("郭达".to_string(), "你".to_string()));
}

#[test]
fn test_split_arr() {
    // 测试英文字符串分割为数组
    let a = "abcdef";
    let v = a.split_char("c");
    assert_eq!(v, vec!["ab".to_string(), "def".to_string()]);

    // 测试中文字符串用逗号分割为数组
    let a = "郭,达欢,迎你,";
    let v = a.split_char(",");
    assert_eq!(v, vec!["郭".to_string(), "达欢".to_string(), "迎你".to_string()]);
}
